﻿using System;
using System.Collections.Generic;
using System.Text;
using StackExchange.Redis;

namespace Sustainalytics.Level2CacheClient
{
    public class RedisClient : ILevel2CacheClient
    {
        private ConnectionMultiplexer redisServer;
        private IDatabase repository;
        public RedisClient(string connectionString, int database)
        {
            if (string.IsNullOrEmpty(connectionString))
                throw new ArgumentException("Connection string cannot be empty");

            redisServer = ConnectionMultiplexer.Connect(connectionString);

            redisServer.ConnectionFailed += redisServer_ConnectionFailed;
                
            repository = redisServer.GetDatabase(database);
        }

        public static ILevel2CacheClient GetLevel2CacheClient(string connectionString, int database)
        {
            RedisClient redisClient = new RedisClient(connectionString, database);

            return redisClient;
        }

        void redisServer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            throw new ArgumentException("Connection to the Cache Server Failed");
        }

        public void AddString(string key, string value) // AddString(string key, string value) // AddSet(string key, string value)
        {
            repository.StringSet(key, value);
        }

        public void AddSet(string key, string value)
        {
            repository.SetAdd(key, value);
        }

        public void AddBytes(string key, byte[] value)
        {
            var str = Encoding.Default.GetString(value);

            repository.StringSet(key, str);
        }

        public IEnumerable<string> GetSetValues(string key)
        {
            List<string> redisOutput = new List<string>();

            RedisValue[] values = repository.SetMembers(key);

            if (values != null)
            {
                foreach (RedisValue value in values)
                {
                    redisOutput.Add(value);
                }
            }
            else
            {
                // throw not found error
            }

            return redisOutput;
        }

        public string GetString(string key)
        {
           return repository.StringGet(key);
        }

        public byte[] GetBytes(string key)
        {
            return repository.StringGet(key);
        }

        public void RemoveString(string key)
        {
            repository.KeyDelete(key);
        }

        public void RemoveSetValue(string key, string value)
        {
            repository.SetRemove(key, value);

        }

        public void RemoveKey(string key)
        {
            repository.KeyDelete(key);
        }
    }
}

